# -*- coding: utf-8 -*-
import scrapy

import json
import logging
from copy import copy, deepcopy
from FDC_spider.items import FdcEstateGuidItem, FdcBuildingItem, FdcRoomItem

logger = logging.getLogger(__name__)


class XiangyangSpider(scrapy.Spider):
    name = 'xiangyang'
    allowed_domains = ['58.19.239.219']
    start_urls = ['http://58.19.239.219:81/xyWeb/project/toList']  # GET
    project_li_url = 'http://58.19.239.219:81/xyWeb/project/queryList'  # POST 项目列表url
    project_detail_url_temp = 'http://58.19.239.219:81/xyWeb/project/toDetail?uuid={}'  # GET 项目详情url
    building_li_url = 'http://58.19.239.219:81/xyWeb/project/queryBuildings'  # POST 楼栋列表url
    room_li_url = 'http://58.19.239.219:81/xyWeb/project/queryHousesGroupByFloor'  # POST 房号列表url

    def start_requests(self):
        """
        获取项目列表（首页）
        :return:
        """
        # 构造POST请求
        headers = {
            'Referer': self.start_urls[0],
        }
        data = dict(pageNo='1', pageSize='12', )
        yield scrapy.FormRequest(
            self.project_li_url,
            headers=headers,
            formdata=data,
            meta=dict(page_num=1, ),
        )

    def parse(self, response):
        """
        获取项目列表
        :param response:
        :return:
        """
        page_num = copy(response.meta['page_num'])
        total_num = 425  # 设置一个初始值，防止翻页时报错
        try:
            ret = json.loads(response.body.decode())
            success = ret['success']
            project_li_url = ret['data']['data']
            total_num = int(ret['data']['totalCount'])
            assert success and project_li_url and total_num
        except:
            logger.error('第{}页 项目列表获取出错'.format(page_num))
        else:
            for project_dict in project_li_url:
                item_eg = FdcEstateGuidItem()
                item_eg['projectName'] = project_dict.get('projectName', None)
                item_eg['projectAddress'] = project_dict.get('address', None)
                item_eg['projectUse'] = project_dict.get('types', None)
                item_eg['districtName'] = project_dict.get('regionName', None)
                item_eg['developerName'] = project_dict.get('orgName', None)
                item_eg['projectId'] = project_dict.get('uuid', None)
                if item_eg['projectId']:
                    # 获取项目详情
                    headers = {
                        'Referer': self.start_urls[0],
                    }
                    yield scrapy.Request(
                        self.project_detail_url_temp.format(item_eg['projectId']),
                        headers=headers,
                        callback=self.parse_project_detail,
                        meta=dict(item_eg=deepcopy(item_eg), ),
                        priority=10,
                    )

                    # 获取楼栋列表
                    headers = {
                        'Referer': self.project_detail_url_temp.format(item_eg['projectId']),
                    }
                    data = dict(projectId=item_eg['projectId'])
                    yield scrapy.FormRequest(
                        self.building_li_url,
                        headers=headers,
                        formdata=data,
                        callback=self.parse_building_li,
                        meta=dict(item_eg=deepcopy(item_eg)),
                        priority=10,
                    )

                else:
                    logger.error('第{}页 {}  项目id获取为空'.format(page_num, item_eg['projectName']))

        # 翻页
        total_page_num = total_num // 12 + 1 if total_num % 12 else total_num // 12
        if page_num < total_page_num:
            page_num += 1
            # 构造翻页请求
            headers = {
                'Referer': self.start_urls[0],
            }
            data = dict(pageNo='{}'.format(page_num), pageSize='12')
            yield scrapy.FormRequest(
                self.project_li_url,
                headers=headers,
                formdata=data,
                callback=self.parse,
                meta=dict(page_num=deepcopy(page_num), ),
                priority=5,
            )

    def parse_project_detail(self, response):
        """
        获取项目详情
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        item_eg['buildingCategory'] = response.xpath(
            "//span[contains(text(),'建筑类别')]/following-sibling::span/text()").extract_first()
        item_eg['totalArea'] = response.xpath(
            "//h3/following-sibling::div//span[contains(text(),'建筑面积')]/following-sibling::span/text()").extract_first()
        item_eg['totalHouseholds'] = response.xpath(
            "//span[contains(text(),'总户数')]/following-sibling::span/text()").extract_first()
        item_eg['salesTel'] = response.xpath(
            "//span[contains(text(),'售楼电话')]/following-sibling::span/text()").extract_first()
        item_eg['estateIntroduction'] = response.xpath(
            "//span[contains(text(),'楼盘介绍')]/following-sibling::span/text()").extract_first()
        # 获取许可证分组
        tr_li = response.xpath("//div[@class='no']/../../..")
        if tr_li:
            for tr in tr_li:
                item_eg['preSalePermit'] = tr.xpath(".//div[@class='no']/text()").extract_first()
                item_eg['certDate'] = tr.xpath(".//div[contains(text(),'发证日期')]/text()").extract_first()
                item_eg['permitSalesArea'] = tr.xpath(".//div[contains(text(),'预售面积')]/text()").extract_first()
                item_eg['permitBuildingNum'] = tr.xpath(".//div[contains(text(),'楼栋号')]/text()").extract_first()
                yield deepcopy(item_eg)
        else:
            item_eg['preSalePermit'] = None
            item_eg['certDate'] = None
            item_eg['permitSalesArea'] = None
            item_eg['permitBuildingNum'] = None
            yield deepcopy(item_eg)

    def parse_building_li(self, response):
        """
        获取楼栋列表
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        try:
            ret = json.loads(response.body.decode())
            success = ret['success']
            bd_li = ret['data']['data']
            assert success and bd_li
        except:
            logger.error('{} 楼栋列表获取出错'.format(item_eg['projectName']))
        else:
            for bd_dict in bd_li:
                item_bd = FdcBuildingItem()
                item_bd['projectName'] = item_eg['projectName']
                item_bd['projectId'] = item_eg['projectId']
                item_bd['districtName'] = item_eg['districtName']
                item_bd['buildingId'] = bd_dict.get('id', None)
                item_bd['blockName'] = bd_dict.get('name', None)
                item_bd['buildingNo'] = bd_dict.get('number', None)
                yield item_bd

                # 获取单元分组
                unit_li = bd_dict.get('units', list())
                if unit_li:
                    for unit_dict in unit_li:
                        unit_id = unit_dict.get('id', None)
                        # unit_id存在时，才有房号列表
                        if unit_id:
                            # 构造POST请求 获取房号列表
                            headers = {
                                'Referer': self.project_detail_url_temp.format(item_bd['projectId']),
                            }
                            data = dict(
                                projectId=item_bd['projectId'],
                                buildingId=item_bd['buildingId'],
                                unitId=unit_id,
                            )
                            yield scrapy.FormRequest(
                                self.room_li_url,
                                headers=headers,
                                formdata=data,
                                callback=self.parse_room_li,
                                meta=dict(item_bd=deepcopy(item_bd), unit_id=deepcopy(unit_id)),
                                priority=10,
                            )
                else:
                    logger.warning(
                        '{}/{}-{}/{} 单元号获取为空'.format(item_bd['projectName'], item_bd['projectId'], item_bd['blockName'],
                                                     item_bd['buildingId']))

    def parse_room_li(self, response):
        """
        获取房号列表
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        unit_id = copy(response.meta['unit_id'])
        try:
            ret = json.loads(response.body.decode())
            floor_li = ret['data']['data']
            success = ret['success']
            assert floor_li and success
        except:
            logger.error(
                '{}/{}-{}/{}-{} 房号列表获取出错'.format(item_bd['projectName'], item_bd['projectId'], item_bd['blockName'],
                                                 item_bd['buildingId'], unit_id))
        else:
            for index, floor_dict in enumerate(floor_li):
                # 获取同楼层下的房号列表
                room_li = floor_dict.get('houses', list())
                if room_li:
                    for room_dict in room_li:
                        item_rm = FdcRoomItem()
                        item_rm['projectId'] = item_bd['projectId']
                        item_rm['blockName'] = item_bd['blockName']
                        item_rm['buildingId'] = item_bd['buildingId']
                        item_rm['roomNo'] = room_dict.get('number', None)
                        item_rm['roomId'] = room_dict.get('id', None)
                        item_rm['roomArea'] = room_dict.get('buildingArea', None)
                        item_rm['roomStructure'] = room_dict.get('dwellStr', None)
                        item_rm['roomFloor'] = room_dict.get('floorId', None)
                        item_rm['roomUse'] = room_dict.get('houseUsageStr', None)
                        item_rm['roomNature'] = room_dict.get('housePropertyStr', None)
                        item_rm['undecoratedPrice'] = room_dict.get('unDecoratedPrice', None)
                        item_rm['saleStatus'] = room_dict.get('sellStatus', None)
                        item_rm['isMortgage'] = room_dict.get('mortgage', None)
                        item_rm['isSealedOff'] = room_dict.get('sealUp', None)
                        item_rm['isLimitSell'] = room_dict.get('limitSell', None)
                        yield item_rm
                else:
                    logger.warning('{}/{}-{}/{}-{} 索引为{}时 房号列表获取为空'.format(item_bd['projectName'], item_bd['projectId'],
                                                                           item_bd['blockName'], item_bd['buildingId'],
                                                                           unit_id, index))
